home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 06 - 1990 / 06.05 May 90 / virusCheck Code / virusCheck.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-11-26  |  6.4 KB  |  156 lines  |  [TEXT/KAHL]

  1. /*    virusCheck.c -- Functions for self-diagnosis of virus infections.
  2.             Copyright © 1989 by Michael S. Morton.
  3.             You may copy, alter, use, and distribute these routines if you
  4.             leave this file unchanged up to this line.
  5.  
  6.         See notes in the “.h” file.
  7.  
  8.         Think C 3.0 version.
  9. */
  10.  
  11. /*    History:
  12.             26-Nov-89 -- MM --    No longer needs strings library.
  13.                                                     Various small documentation changes.
  14.              6-Nov-89 -- MM --    First version.
  15.  
  16.         Enhancements needed:
  17.             • Should we do a ReleaseResource for some resources, to ditch the
  18.                 master pointer which gets allocated only because we asked for it?
  19.                 How can we know when to do this?  For CODE resources, it’s not a
  20.                 big problem, since there aren’t vast numbers of them.
  21.             • Consider checking if the ROM/System file is recent enough for us
  22. */
  23.  
  24. #include "virusCheck.h"                                    /* get our own prototypes */
  25.  
  26. /*    Local prototypes: */
  27. static void fail (char *kind, ResType type, long actual, long expected);
  28. static void append (char **pPtr, char *s);
  29.  
  30. /*    vResCheck -- Check that the resources of a specified type in the application
  31.         haven’t been altered.  Return TRUE if there’s apparent tampering.
  32. */
  33. extern Boolean vResCheck (type, expectedCount, expectedLen, report)
  34.     register ResType type;                                /* INPUT: type of resource to sum */
  35.     register short expectedCount;                    /* INPUT: expected number of resources */
  36.     register long expectedLen;                        /* INPUT: exp. total len of resources */
  37.     register short report;                                /* INPUT: >0 => report errors w/debugger */
  38. {    register short actCount;                            /* actual count of rsrcs of this type */
  39.     register long actLen;                                    /* actual total length of resources */
  40.     register Handle rsrc;                                    /* resource to check */
  41.  
  42.     register Boolean failFlag = false;        /* any problems encountered? */
  43.  
  44.     register short oldResFile;                        /* for preserving current resource file */
  45.     register Boolean oldResLoad;                    /* for preserving “ResLoad” flag */
  46.  
  47.     /*    Switch to the application’s resource file.  Note that all resource
  48.             calls from here on are the “one deep” calls from Inside Mac, vol. IV. */
  49.     /*    You can swap the order of the next two lines: */
  50.     oldResFile = CurResFile ();                        /* remember initial resource file */
  51.     oldResLoad = ResLoad;                                    /* remember “ResLoad” state */
  52.  
  53.     /*    You can swap the order of the next two lines: */
  54.     UseResFile (CurApRefNum);                            /* search application for resources */
  55.     SetResLoad (false);                                        /* don’t load the resources right away */
  56.  
  57.     /*    You can swap the order of the next two lines: */
  58.     actLen = 0;                                                        /* initialize length */
  59.     actCount = Count1Resources (type);        /* how many of this type are there? */
  60.  
  61.     if (actCount != expectedCount)
  62.     {    if (report > 0)                                            /* is the developer listening? */
  63.             fail ("count", type, actCount, expectedCount);
  64.         failFlag = true;                                        /* TAMPERING DETECTED */
  65.     }                                                                            /* end of mismatched resource count */
  66.  
  67.     while (actCount)                                            /* loop actCount down to 1 */
  68.     {    /*    Get the resource’s handle, but don’t load it. */
  69.         rsrc = Get1IndResource (type, actCount); /* see if it’s already in memory */
  70.         if (! rsrc)                                                    /* not available? */
  71.         {    if (report > 0)                                        /* is the developer listening? */
  72.                 DebugStr ("\pResource not available!");
  73.             failFlag = true;                                    /* error detected; ASSUME TAMPERING */
  74.             goto EXIT;                                                /* sorry, Dr. Dijkstra */
  75.         }
  76.  
  77.         /*    You can swap the order of the next two lines: */
  78.         actLen += SizeResource (rsrc);            /* sum up length of rsrcs of this type */
  79.         --actCount;                                                    /* get next index number */
  80.     }                                                                            /* end of loop through resources */
  81.  
  82.     if (actLen != expectedLen)
  83.     {    if (report > 0)                                            /* is the developer listening? */
  84.             fail ("length", type, actLen, expectedLen);
  85.         failFlag = true;                                        /* TAMPERING DETECTED */
  86.     }
  87.  
  88. EXIT:                                                                     /* goto here on tampering or error */
  89.     /*    You can swap the order of the next two lines: */
  90.     UseResFile (oldResFile);                            /* restore original resource file */    
  91.     SetResLoad (oldResLoad);                            /* restore original loading state */
  92.  
  93.     return failFlag;                                            /* TRUE => error or tampering */
  94. }                                                                                /* end of vResCheck () */
  95.  
  96. /*    vCodeCheck -- Check that CODE resources haven’t been altered.
  97. */
  98. extern Boolean vCodeCheck (expectedCount, expectedLen, report)
  99.     register short expectedCount;                    /* expected number of CODEs */
  100.     register long expectedLen;                        /* expected total size of CODEs */
  101.     register short report;                                /* INPUT: >0 => report errors w/debugger */
  102. {    
  103.     return vResCheck ('CODE', expectedCount, expectedLen, report);
  104. }                                                                                /* end of vCodeCheck () */
  105.  
  106. /*    fail -- dump a string like:
  107.             Got <kind> <actual> for resource type '<type>', instead of <expected>
  108. */
  109. static void fail (kind, type, actual, expected)
  110.     char *kind;                                                        /* INPUT: "count" or "length" */
  111.     ResType type;                                                    /* INPUT: resource type which failed */
  112.     long actual, expected;                                /* INPUT: counts or lengths */
  113. {    char buffer [100];                                        /* for accumulating output message */
  114.     char *bufp;                                                        /* pointer into buffer[] */
  115.     Str255 actualText, expectedText;            /* formatted from params */
  116.     union                                                                    /* to get ResType to be like string */
  117.     {    char resName [5];
  118.         ResType theType;
  119.     } u;
  120.  
  121.     NumToString ((long) actual, & actualText);
  122.     PtoCstr ((char *) & actualText);
  123.     NumToString ((long) expected, & expectedText);
  124.     PtoCstr ((char *) & expectedText);
  125.     u.theType = type;                                            /* set up resource type… */
  126.     u.resName [4] = '\0';                                    /* …to be a NUL-ended C string */
  127.  
  128.     bufp = buffer;                                                /* point to output buffer */
  129.     append (& bufp, "Got ");
  130.     append (& bufp, kind);
  131.     append (& bufp, " ");
  132.     append (& bufp, (char *) & actualText);
  133.     append (& bufp, " for resource type '");
  134.     append (& bufp, u.resName);
  135.     append (& bufp, "' instead of ");
  136.     append (& bufp, (char *) & expectedText);
  137.     *bufp++ = '\0';
  138.     CtoPstr (buffer);
  139.     DebugStr (buffer);
  140. }                                                                                /* end of fail () */
  141.  
  142. /*    append -- Append a string to an output buffer.  This routine lets us
  143.         avoid pulling in the “strings” library.
  144. */
  145. static void append (pPtr, s)
  146.     char **pPtr;                                                    /* UPDATE: VAR ptr to output */
  147.     register char *s;                                            /* INPUT: string to append */
  148. {    register char *p;                                            /* output ptr */
  149.     register char c;
  150.  
  151.     p = *pPtr;                                                        /* pick up output pointer */
  152.     while (c = *s++)                                            /* loop through all non-nulls… */
  153.         *p++ = c;                                                        /* …storing them in buffer */
  154.     *pPtr = p;                                                        /* return updated output pointer */
  155. }                                                                                /* end of append () */
  156.